Skip to content

fix: add content-type check for non-JSON responses in fetchExternal#825

Closed
Pavan-Microsoft wants to merge 2 commits into
devfrom
psl-pk-40958-user-fetch-html-error
Closed

fix: add content-type check for non-JSON responses in fetchExternal#825
Pavan-Microsoft wants to merge 2 commits into
devfrom
psl-pk-40958-user-fetch-html-error

Conversation

@Pavan-Microsoft

Copy link
Copy Markdown
Contributor

Purpose

This pull request adds stricter response validation to the HttpClient utility by ensuring that all HTTP responses are JSON before attempting to parse them. This helps prevent runtime errors and improves error handling.

Improvements to error handling:

  • src/App/src/utils/httpClient.ts: Added a check to verify that the content-type header includes application/json before parsing the response, and throw a descriptive error if not.

Does this introduce a breaking change?

  • Yes
  • No

Golden Path Validation

  • I have tested the primary workflows (the "golden path") to ensure they function correctly without errors.

Deployment Validation

  • I have validated the deployment process successfully and all services are running as expected with this change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens HttpClient.fetchExternal() response validation by verifying the response Content-Type indicates JSON before attempting to parse, aiming to improve runtime safety and error clarity for non-API endpoints (e.g., /.auth/me).

Changes:

  • Add a Content-Type header check in fetchExternal() and throw a descriptive error for non-JSON responses.
  • Preserve existing response.ok handling while improving the failure mode for unexpected response bodies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

throw new Error(`${config.method || 'GET'} ${url} failed: ${response.statusText}`);
}
const contentType = response.headers.get('content-type') || '';
if (!contentType.includes('application/json')) {

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON detection is overly strict: valid JSON responses may use vendor/problem types like application/problem+json or application/vnd.api+json, and header values are case-insensitive. Consider normalizing to lowercase and accepting application/json or any +json media type (per RFC 6839) to avoid false negatives.

Suggested change
if (!contentType.includes('application/json')) {
const normalizedContentType = contentType.toLowerCase();
const mediaType = normalizedContentType.split(';', 1)[0].trim();
const isJsonResponse = mediaType === 'application/json' || mediaType.endsWith('+json');
if (!isJsonResponse) {

Copilot uses AI. Check for mistakes.
if (!response.ok) {
throw new Error(`${config.method || 'GET'} ${url} failed: ${response.statusText}`);
}
const contentType = response.headers.get('content-type') || '';

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message can be unhelpful when the server omits the Content-Type header (you'll end up with returned non-JSON response ()). Consider distinguishing between a missing header and a non-JSON header value so the thrown error is actionable during debugging.

Suggested change
const contentType = response.headers.get('content-type') || '';
const contentType = response.headers.get('content-type');
if (!contentType) {
throw new Error(`${config.method || 'GET'} ${url} returned response missing Content-Type header`);
}

Copilot uses AI. Check for mistakes.
Comment on lines +71 to 75
const contentType = response.headers.get('content-type') || '';
if (!contentType.includes('application/json')) {
throw new Error(`${config.method || 'GET'} ${url} returned non-JSON response (${contentType})`);
}
return response.json();

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says the HttpClient now ensures all HTTP responses are JSON before parsing, but this validation is only added to fetchExternal(); the core request() path still calls response.json() unconditionally. Either broaden the check to request() as well or adjust the PR description to match the actual behavior.

Copilot uses AI. Check for mistakes.
@Pavan-Microsoft
Pavan-Microsoft deleted the psl-pk-40958-user-fetch-html-error branch April 23, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants